// Table.ts
import { type ITableOptions, type IBaseData } from '../types'
import { CanvasRenderer } from './CanvasRenderer'

// 定义事件调度接口
interface EventDispatcher {
  addEventListener: (type: string, listener: (event: CustomEvent) => void) => void
  removeEventListener: (type: string, listener: (event: CustomEvent) => void) => void
  dispatchEvent: (event: CustomEvent) => void
}

// 事件调度Mixin
class EventDispatcherImpl {
  private _listeners: Record<string, Array<(event: CustomEvent) => void>> = {}

  public addEventListener (type: string, listener: (event: CustomEvent) => void): void {
    if (!this._listeners[type]) {
      this._listeners[type] = []
    }
    this._listeners[type].push(listener)
  }

  public removeEventListener (type: string, listener: (event: CustomEvent) => void): void {
    const listeners = this._listeners[type]
    if (listeners) {
      const index = listeners.indexOf(listener)
      if (index > -1) {
        listeners.splice(index, 1)
      }
    }
  }

  public dispatchEvent (event: CustomEvent): void {
    const listeners = this._listeners[event.type]
    if (listeners) {
      for (const listener of listeners) {
        listener(event)
      }
    }
  }
}

export class Table implements EventDispatcher {
  private readonly options: Required<ITableOptions>

  // 从EventDispatcherImpl继承的属性和方法
  private readonly _listeners: Record<string, Array<(event: CustomEvent) => void>> = {}
  public addEventListener!: (type: string, listener: (event: CustomEvent) => void) => void
  public removeEventListener!: (type: string, listener: (event: CustomEvent) => void) => void
  public dispatchEvent!: (event: CustomEvent) => void
  private renderer: CanvasRenderer
  private data: IBaseData[] = []
  private selectedRowIndices: number[] = []
  private hoverRow: number = -1 // 当前悬停的行索引

  constructor (options: ITableOptions) {
    this.options = {
      rowHeight: 32,
      ...options
    }

    // 初始化事件系统
    this._listeners = {}
    this.addEventListener = EventDispatcherImpl.prototype.addEventListener.bind(this)
    this.removeEventListener = EventDispatcherImpl.prototype.removeEventListener.bind(this)
    this.dispatchEvent = EventDispatcherImpl.prototype.dispatchEvent.bind(this)

    this.initRenderer()
    this.setupEvents()
  }

  private initRenderer (): void {
    const { container, columns, rowHeight, dataSource } = this.options
    const rect = container.getBoundingClientRect()

    // 移除父容器滚动样式
    container.style.height = ''
    container.style.overflowY = ''

    this.renderer = new CanvasRenderer({
      container: this.options.container,
      width: rect.width,
      height: rect.height,
      columns,
      rowHeight,
      dataSource,
      dpr: window.devicePixelRatio || 1,
      getRowData: (index) => this.data[index],
      getTotalRows: () => this.data.length,
      selectionMode: this.options?.selectionMode
    })

    container.appendChild(this.renderer.canvas)
    this.updateData(dataSource) // 新增：初始化时同步数据
  }

  private setupEvents (): void {
    // 添加点击事件监听器
    this.options.container.addEventListener('click', (event) => {
      const rect = this.options.container.getBoundingClientRect()
      const x = event.clientX - rect.left
      const y = event.clientY - rect.top

      // 计算点击的行索引
      const rowHeight = this.options.rowHeight || 32
      const rowIndex = Math.floor(y / rowHeight)

      // 如果启用了 selectionMode 且点击位置在左侧 40px 区域内
      if (this.options.selectionMode && x >= 0 && x <= 40) {
        // 判断是否点击的是表头区域
        if (rowIndex === 0 && y < rowHeight) {
          // 表头勾选框被点击，触发全选/取消全选
          if (this.selectedRowIndices.length === this.options.dataSource?.length) {
            this.selectedRowIndices = []
          } else {
            this.selectedRowIndices = this.options.dataSource?.map((_, i) => i) || []
          }
          this.dispatchEvent(new CustomEvent('selectionChange', { detail: this.selectedRowIndices }))
        } else {
          // 内容行勾选框被点击，切换当前行选择状态
          this.selectRow(rowIndex)
        }
      }
    })

    // 新增：监听鼠标移动事件以更新悬停状态
    this.options.container.addEventListener('mousemove', (event) => {
      const rect = this.options.container.getBoundingClientRect()
      const y = event.clientY - rect.top

      // 计算悬停的行索引
      const rowHeight = this.options.rowHeight || 32
      const rowIndex = Math.floor(y / rowHeight)

      if (rowIndex !== this.hoverRow) {
        this.hoverRow = rowIndex
        // 触发重绘
        this.renderer.requestRedraw()
      }
    })
  }

  public updateData (newData: IBaseData[]): void {
    this.data = newData ? [...newData] : this.data
    this.renderer.updateData(newData)
  }

  public destroy (): void {
    this.renderer.destroy()
  }

  public selectRow (index: number): void {
    if (this.options.selectionMode === 'single') {
      this.selectedRowIndices = [index]
    } else if (this.options.selectionMode === 'multiple') {
      const idx = this.selectedRowIndices.indexOf(index)
      if (idx > -1) {
        this.selectedRowIndices.splice(idx, 1)
      } else {
        this.selectedRowIndices.push(index)
      }
    }
    this.dispatchEvent(new CustomEvent('selectionChange', { detail: this.selectedRowIndices }))
  }

  public getSelectedRows (): number[] {
    return this.selectedRowIndices
  }
}
